 <!-- 
  多相机同步渲染
  裁剪： setScissor ( x : Integer, y : Integer, width : Integer, height : Integer ) : undefined
将剪裁区域设为(x, y)到(x + width, y + height) Sets the scissor area from
  启用/禁用裁剪： setScissorTest
  -->
  <template>
    <div ref="Cavans"></div>
</template>
<script setup>
import { createHelper, resizeHandler, THREE, createGui } from '@/utils/threejs'
// import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { OrbitControls } from 'three/addons/controls/OrbitControls'
import { DragControls } from 'three/examples/jsm/controls/DragControls'
import Stats from 'three/examples/jsm/libs/stats.module';

const Cavans = ref(null)
const count = ref(0)
const guiConfig = {
    wireframe: false,
    // 相机切换
    switchCamera: () => {
        if(currentCamera === watcherCamera){
            currentCamera = camera
            controls.enabled = false
            dragControls.disconnect()
        } else {
            currentCamera = watcherCamera
            controls.enabled = true
            dragControls.connect()
        }
    }
}
let currentCamera
// 创建一个场景
const scene = new THREE.Scene()
// 初始化调试
const gui = createGui()
const w = document.body.clientWidth
const h = document.body.clientHeight
let aspect = w / h
// 创建一个正交相机   
const camera = new THREE.OrthographicCamera( -aspect, aspect, aspect, -aspect, 0.1, 1000 )
scene.add(camera)
camera.lookAt(scene.position)
// 相机位置
camera.position.set(1, 1, 2);// 相机默认坐标是(0,0,0)
// 添加第二个正交相机  
const watcherCamera = new THREE.OrthographicCamera( -2, 2, 2, -2, 0.1, 1000 )
watcherCamera.position.set(1, 1, 2)
watcherCamera.lookAt(scene.position)
scene.add(watcherCamera)
currentCamera = watcherCamera
// 渲染器
const renderer = new THREE.WebGLRenderer({
    antialias: true, // 抗锯齿
})
// 优化 设置像素比
const dpr = window.devicePixelRatio
renderer.setScissorTest(true)
// 创建全局裁剪
const clipScence = () => {
    // 剪裁
    renderer.setScissor(0, 0, w, h)
    renderer.setClearColor(0Xe6e6e6)
    renderer.setPixelRatio(dpr || 1)
    // 渲染器的尺寸
    renderer.setSize(w, h)
	renderer.render( scene, watcherCamera )
}
// 创建缩略图裁剪
const clipThumbnail = () => {
    // 剪裁
    const bottom = 20
    const left = w - 150 - 20
    renderer.setScissor(left, bottom, 150, 200)
    renderer.setClearColor(0X3ea2b6)
    renderer.setPixelRatio(dpr || 1)
    renderer.setViewport(left, bottom, 150, 200)
	renderer.render( scene, camera )
    // 更新相机相关
    camera.position.copy(watcherCamera.position)
    camera.rotation.copy(watcherCamera.rotation)
    camera.zoom = watcherCamera.zoom
    // 更新相机矩阵
    camera.updateProjectionMatrix()
}
// 创建辅助
createHelper(scene)
// geometry 几何体 创建一个立方体 BoxGeometry
const geometry = new THREE.BoxGeometry( 1, 1, 1 )
// 添加全局光照 AmbientLight ambientlight( color : Integer, intensity : Float ) 环境光会均匀的照亮场景中的所有物体。
// color - (参数可选）颜色的rgb数值。缺省值为 0xffffff。 十六进制
// intensity - (参数可选)光照的强度。缺省值为 1。
const light = new THREE.AmbientLight(0xffffff, 0.5)
// 添加方向光 平行光（directionallight） 平行光是沿着特定方向发射的光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
scene.add(light, directionalLight)
// 颜色
const color = new THREE.Color(Math.random(), Math.random(), Math.random())
const faces = []
for(let i = 0; i < geometry.groups.length; i++){
    const material = new THREE.MeshBasicMaterial({
        color: new THREE.Color(Math.random(), Math.random(), Math.random()),
    })
    faces.push(material)
}
// Mesh 网格  网格包含一个几何体 geometry 以及作用在此几何体上的材质 material
const cube = new THREE.Mesh( geometry, faces );
// 调用 scene.add()，物体将会被添加到 (0,0,0) 坐标
scene.add(cube)
const controls = new OrbitControls(currentCamera, renderer.domElement) 
// 将其设置为true以启用阻尼（惯性），这将给控制器带来重量感。默认值为false。 请注意，如果该值被启用，你将必须在你的动画循环里调用update()
controls.enableDamping = true 
// 当.enableDamping设置为true的时候，阻尼惯性有多大。 Default is 0.05. 请注意，要使得这一值生效，你必须在你的动画循环里调用 update()
controls.dampingFactor = 0.03
// 拖拽控制器
const dragControls = new DragControls([cube], currentCamera, renderer.domElement)
dragControls.addEventListener('dragstart', ()=>{
    console.log('dragstart')
    controls.enabled = false
})
dragControls.addEventListener('dragend', ()=>{
    console.log('end')
    controls.enabled = true
})
// 添加性能监控器
const stats = new Stats()
stats.setMode(0)
const animate = () => {
    // 浏览器API
	requestAnimationFrame( animate );
    controls.update() // 更新轨道控制器 
    stats.update() // 更新监控帧数
	// renderer.render( scene, currentCamera );
    clipScence()
    clipThumbnail()
}
animate();
// 自适应
resizeHandler(renderer, currentCamera)
// gui 调试
// gui.add() 
// 参数 target: object, propName: never, min?: number, max?: number, step?: number
gui.add(cube.rotation,'x',1,10,1).name('rotationX')
// 参数为自定义对象
gui.add(guiConfig,'wireframe').onChange((val)=>{
    // wireframe 是否启用线框模式，默认为 false
    cube.material.forEach((item)=>item.wireframe=val)
})
// 参数为函数
gui.add(guiConfig,'switchCamera')
onMounted(()=>{
    // 挂载
    Cavans.value.appendChild(renderer.domElement)
    Cavans.value.appendChild(stats.domElement)
})
</script>
